package com.example.myapplication.data.repository

import com.example.myapplication.data.database.StorageItemDao
import com.example.myapplication.data.database.toEntity
import com.example.myapplication.data.database.toModel
import com.example.myapplication.data.model.StorageItem
import com.example.myapplication.data.model.ItemWithPath
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.map
import javax.inject.Inject
import javax.inject.Singleton
import kotlinx.coroutines.runBlocking

/**
 * 储物物品数据仓库接口
 */
interface StorageItemRepository {
    
    /**
     * 根据储物空间ID获取所有物品
     */
    fun getItemsBySpaceId(spaceId: String): Flow<List<StorageItem>>
    
    /**
     * 根据ID获取物品
     */
    suspend fun getItemById(id: String): StorageItem?
    
    /**
     * 根据ID获取物品（Flow版本）
     */
    fun getItemByIdFlow(id: String): Flow<StorageItem?>
    
    /**
     * 获取所有物品
     */
    fun getAllItems(): Flow<List<StorageItem>>
    
    /**
     * 搜索物品
     */
    fun searchItems(query: String): Flow<List<StorageItem>>
    
    /**
     * 搜索物品并返回路径信息
     */
    fun searchItemsWithPath(query: String): Flow<List<ItemWithPath>>
    
    /**
     * 根据标签搜索物品
     */
    fun getItemsByTag(tag: String): Flow<List<StorageItem>>
    
    /**
     * 获取指定数量范围的物品
     */
    fun getItemsByQuantityRange(minQuantity: Int, maxQuantity: Int): Flow<List<StorageItem>>
    
    /**
     * 插入或更新物品
     */
    suspend fun insertOrUpdateItem(item: StorageItem): Long
    
    /**
     * 批量插入物品
     */
    suspend fun insertItems(items: List<StorageItem>)
    
    /**
     * 删除物品
     */
    suspend fun deleteItem(item: StorageItem)
    
    /**
     * 根据ID删除物品
     */
    suspend fun deleteItemById(id: String)
    
    /**
     * 迁移物品到新的储物空间
     */
    suspend fun migrateItem(itemId: String, newSpaceId: String)
    
    /**
     * 批量迁移物品
     */
    suspend fun migrateItems(itemIds: List<String>, newSpaceId: String)
    
    /**
     * 获取储物空间中的物品总数
     */
    suspend fun getItemCountBySpaceId(spaceId: String): Int
    
    /**
     * 获取所有物品的总数量
     */
    suspend fun getTotalQuantityBySpaceId(spaceId: String): Int
}

/**
 * 储物物品数据仓库实现
 */
@Singleton
class StorageItemRepositoryImpl @Inject constructor(
    private val storageItemDao: StorageItemDao,
    private val storageSpaceRepository: StorageSpaceRepository
) : StorageItemRepository {
    
    override fun getItemsBySpaceId(spaceId: String): Flow<List<StorageItem>> {
        return storageItemDao.getItemsForSpace(spaceId).map { entities ->
            entities.map { it.toModel() }
        }
    }
    
    override suspend fun getItemById(id: String): StorageItem? {
        return storageItemDao.getItemById(id)?.toModel()
    }
    
    override fun getItemByIdFlow(id: String): Flow<StorageItem?> {
        return storageItemDao.getItemByIdFlow(id).map { entity ->
            entity?.toModel()
        }
    }
    
    override fun getAllItems(): Flow<List<StorageItem>> {
        return storageItemDao.getAllItems().map { entities ->
            entities.map { it.toModel() }
        }
    }
    
    override fun searchItems(query: String): Flow<List<StorageItem>> {
        return storageItemDao.searchItems(query).map { entities ->
            entities.map { it.toModel() }
        }
    }
    
    override fun searchItemsWithPath(query: String): Flow<List<ItemWithPath>> {
        return storageItemDao.searchItems(query).map { entities ->
            entities.map { entity ->
                val item = entity.toModel()
                val path = getItemPathSync(item.spaceId)
                ItemWithPath(item = item, path = path)
            }
        }
    }
    
    private fun getItemPathSync(spaceId: String): List<com.example.myapplication.data.model.StorageSpace> {
        // 同步版本，在协程中调用
        return runBlocking {
            val path = mutableListOf<com.example.myapplication.data.model.StorageSpace>()
            var currentSpace = storageSpaceRepository.getSpaceById(spaceId)
            
            while (currentSpace != null) {
                path.add(0, currentSpace) // 添加到列表开头，保持从根到叶的顺序
                currentSpace = currentSpace.parentId?.let { storageSpaceRepository.getSpaceById(it) }
            }
            
            path
        }
    }
    
    override fun getItemsByTag(tag: String): Flow<List<StorageItem>> {
        return storageItemDao.getItemsByTag(tag).map { entities ->
            entities.map { it.toModel() }
        }
    }
    
    override fun getItemsByQuantityRange(minQuantity: Int, maxQuantity: Int): Flow<List<StorageItem>> {
        return storageItemDao.getItemsByQuantityRange(minQuantity, maxQuantity).map { entities ->
            entities.map { it.toModel() }
        }
    }
    
    override suspend fun insertOrUpdateItem(item: StorageItem): Long {
        return storageItemDao.insertItem(item.toEntity())
    }
    
    override suspend fun insertItems(items: List<StorageItem>) {
        storageItemDao.insertItems(items.map { it.toEntity() })
    }
    
    override suspend fun deleteItem(item: StorageItem) {
        storageItemDao.deleteItem(item.toEntity())
    }
    
    override suspend fun deleteItemById(id: String) {
        storageItemDao.deleteItemById(id)
    }
    
    override suspend fun migrateItem(itemId: String, newSpaceId: String) {
        storageItemDao.migrateItem(itemId, newSpaceId)
    }
    
    override suspend fun migrateItems(itemIds: List<String>, newSpaceId: String) {
        storageItemDao.migrateItems(itemIds, newSpaceId)
    }
    
    override suspend fun getItemCountBySpaceId(spaceId: String): Int {
        return storageItemDao.getItemCountBySpaceId(spaceId)
    }
    
    override suspend fun getTotalQuantityBySpaceId(spaceId: String): Int {
        return storageItemDao.getTotalQuantityBySpaceId(spaceId) ?: 0
    }
} 